package main

import (
	"context"
	"flag"
	"log"
	"net/http"
	"os"
	"os/signal"
	"strings"
	"syscall"
	"time"

	"github.com/robfig/cron/v3"
	"gopkg.in/natefinch/lumberjack.v2"

	"go-learn/go_learn/prometheus/web_hook/global"
	"go-learn/go_learn/prometheus/web_hook/pkg/logger"
	"go-learn/go_learn/prometheus/web_hook/pkg/oss"
	"go-learn/go_learn/prometheus/web_hook/pkg/setting"
	"go-learn/go_learn/prometheus/web_hook/router"
)

var (
	h            bool
	defaultRobot string
	config       string
)

func init() {
	setupFlag()

	err := setupSetting()
	if err != nil {
		log.Fatalf("init.setupSetting err: %v", err)
	}
	err = setupLogger()
	if err != nil {
		log.Fatalf("init.setupLogger err: %v", err)
	}
}

func main() {
	if h {
		flag.Usage()
		return
	}
	initCron()

	route := router.NewRouter()
	s := &http.Server{
		Addr:           ":" + global.ServerSetting.HttpPort,
		Handler:        route,
		ReadTimeout:    global.ServerSetting.ReadTimeout,
		WriteTimeout:   global.ServerSetting.WriteTimeout,
		MaxHeaderBytes: 1 << 20,
	}

	go func() {
		if err := s.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			log.Fatalf("s.ListenAndServe err:%v", err)
		}
	}()

	quit := make(chan os.Signal)
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
	<-quit
	log.Println("shuting down server...")

	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()
	if err := s.Shutdown(ctx); err != nil {
		log.Fatal("server forced to shutdown:", err)
	}

	log.Println("server exiting")
}

func setupFlag() {
	flag.BoolVar(&h, "h", false, "help")
	// go run main.go -defaultRobot https://oapi.dingtalk.com/robot/send?access_token=56afcf0da4735e3be0e94a37c81b5f766843eabb57d0742c25d5a85df7fa9502
	flag.StringVar(&defaultRobot, "defaultRobot", "", "global dingtalk robot webhook, you can overwrite by alert rule with annotations dingtalkRobot")
	flag.StringVar(&config, "config", "config/", "指定要使用的配置文件路径")

	flag.Parse()
}

func setupSetting() error {
	s, err := setting.NewSetting(strings.Split(config, ",")...)
	if err != nil {
		return err
	}

	err = s.ReadSection("Server", &global.ServerSetting)
	err = s.ReadSection("Oss", &global.Oss)
	if err != nil {
		return err
	}
	err = s.ReadSection("Prometheus", &global.Prometheus)
	if err != nil {
		return err
	}
	err = s.ReadSection("HtmlToImg", &global.HtmlToImg)
	if err != nil {
		return err
	}
	err = s.ReadSection("DefaultRobot", &global.DefaultRobot)
	if err != nil {
		return err
	}
	err = s.ReadSection("Robot", &global.Robot)
	if err != nil {
		return err
	}
	err = s.ReadSection("AppSetting", &global.AppSetting)
	if err != nil {
		return err
	}

	global.ServerSetting.ReadTimeout *= time.Second
	global.ServerSetting.WriteTimeout *= time.Second
	global.ServerSetting.ContextTimeout *= time.Second

	return nil
}

func setupLogger() error {
	fileName := global.AppSetting.LogSavePath + "/" + global.AppSetting.LogFileName + global.AppSetting.LogFileExt
	global.Logger = logger.NewLogger(&lumberjack.Logger{
		Filename:  fileName,
		MaxSize:   500,
		MaxAge:    10,
		LocalTime: true,
	}, "", log.LstdFlags).WithCaller(2)

	return nil
}

// initCron 初始化定时任务
func initCron() {
	c := cron.New()
	// 0 0 0 * * *
	_, err := c.AddFunc("0 10 * * *", func() {
		ossClient, _ := oss.NewOss(global.Oss)
		ossClient.ClearOssByDate(10)
	})
	if err != nil {
		log.Fatal(err)
	}

	c.Start()
}
